import numpy as np
import cv2
from sklearn.cluster import KMeans
import gradio as gr

#使用sklearn对图像进行K-means聚类
def kmeans_clustering_sklearn(image,k=5):
    #准备好RGB三列颜色矩阵
    data = image.reshape((-1,3))
    #通过kmeans聚类对图像进行聚类
    kmeans=KMeans(n_clusters=k,random_state=0,n_init=10)
    labels=kmeans.fit_predict(data)
    centers=kmeans.cluster_centers_
    #将聚类后的数据转换为图像
    result = centers[labels].reshape(image.shape)
    cluster_img = (result - result.min()) / (result.max() - result.min())
    return cluster_img, centers

#定义gradio函数
def gradio_app(image):
    #获取图像的主色调
    cluster_img, centers =kmeans_clustering_sklearn(image,5)
    #生成十六进制
    hexadecimal_colors = ["#%02x%02x%02x" % (int(color[0]), int(color[1]), int(color[2])) for color in centers]
    #创建一个空的数组，存放调色板颜色
    back = np.zeros((100, 100 * len(hexadecimal_colors ), 3), dtype=np.uint8)
    for i, color in enumerate(hexadecimal_colors ):
        hex_color = tuple(int(color[i:i + 2], 16) for i in (1, 3, 5))
        back[:, i * 100:(i + 1) * 100] = np.array(hex_color)


    # 返回颜色调色板图像和颜色调色板的十六进制表示
    return back, "\n".join(hexadecimal_colors)   


# 创建 gradio 用户界面  
iface = gr.Interface(  
    fn=gradio_app, # 指定 gradio 应用函数  
    inputs=gr.components.Image(), # 定义输入类型为图像  
      
    # 定义输出类型为图像、文本和颜色列表  
    outputs=[
        gr.components.Image(type="numpy",show_label=False,width=300),
        gr.components.Text(label="色彩十六进制码")
    ], 
    title="KMeans调色板提取器", # 定义应用标题  
    description="上传图像并获取其调色板。" # 定义应用描述  
)  
  
iface.launch(share=True) # 启动 gradio 应用  



